package com.ccteam.fluidmusic.ui.local.album

import android.net.Uri
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaMetadataCompat
import androidx.lifecycle.*
import com.ccteam.fluidmusic.ui.PARENT_ID_KEY
import com.ccteam.fluidmusic.fluidmusic.common.MusicServiceConnectionFlow
import com.ccteam.fluidmusic.fluidmusic.media.extensions.METADATA_KEY_ALBUM_ID
import com.ccteam.fluidmusic.fluidmusic.media.extensions.METADATA_KEY_ARTIST_ID
import com.ccteam.fluidmusic.fluidmusic.media.extensions.id
import com.ccteam.fluidmusic.utils.cancelIfActive
import com.ccteam.shared.result.BaseItemData
import com.ccteam.shared.result.album.AlbumDetailFootItem
import com.ccteam.shared.result.album.AlbumDetailHeaderItem
import com.ccteam.shared.result.album.AlbumDetailMusicItem
import com.ccteam.shared.result.artist.ArtistInfoData
import com.ccteam.shared.utils.NO_PLAYING
import com.ccteam.shared.utils.PLAYING
import com.ccteam.shared.utils.getPlaybackStatus
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

/**
 *
 * @author Xiaoc
 * @since 2021/1/6
 *
 * 本地详细歌曲页面显示的ViewModel
 * 通过 [parentId] 进行注册回调显示对应歌曲数据
 */
@HiltViewModel
class LocalMusicAlbumDetailViewModel @Inject constructor(
    private val musicServiceConnectionFlow: MusicServiceConnectionFlow,
    savedStateHandle: SavedStateHandle
): ViewModel() {

    private val _albumDetailData = MutableLiveData<List<BaseItemData>>(mutableListOf())
    val albumDetailData: LiveData<List<BaseItemData>> = _albumDetailData

    var headerItem: AlbumDetailHeaderItem? = null

    private var parentId: String? = null

    /**
     * 订阅回调
     * 收到具体专辑内容的信息后进入协程进行处理
     */
    private val subscriptionCallback = object : MediaBrowserCompat.SubscriptionCallback() {
        override fun onChildrenLoaded(parentId: String, children: List<MediaBrowserCompat.MediaItem>) {
            viewModelScope.launch {
                handleAlbumMusicMediaData(children)
            }
        }
    }

    private var metadataChangJob: Job? = null
    init {
        savedStateHandle.get<String>(PARENT_ID_KEY)?.let {
            this.parentId = it
            musicServiceConnectionFlow.subscribe(it, subscriptionCallback)

            metadataChangJob = viewModelScope.launch(Dispatchers.Default) {
                musicServiceConnectionFlow.nowPlaying.collectLatest { metadata ->
                    _albumDetailData.postValue(handleAlbumMusicMediaDataChanged(metadata))
                }
            }
        }
    }

    /**
     * 设置专辑头部数据内容
     * 仅在第一次设置时有效
     */
    fun setAlbumHeaderFoot(headerItem: AlbumDetailHeaderItem){
        if(_albumDetailData.value.isNullOrEmpty()){
            this.headerItem = headerItem
            _albumDetailData.value = mutableListOf(headerItem)
        }
    }

    /**
     * 使用协程处理回调数据
     * 并加入Header头部显示专辑的信息
     */
    private suspend fun handleAlbumMusicMediaData(children:List<MediaBrowserCompat.MediaItem>){
        withContext(Dispatchers.Default){
            val itemsList = mutableListOf<BaseItemData>()
            if(children.isNotEmpty()){
                itemsList.add(headerItem!!)
                itemsList.addAll(
                    children.map { child ->
                        val artistInfo = child.description.extras?.getString(METADATA_KEY_ARTIST_ID)?.let {
                            listOf(ArtistInfoData(it,child.description.subtitle.toString()))
                        } ?: emptyList()
                        AlbumDetailMusicItem(
                            mediaId = child.mediaId!!,
                            artist = child.description.subtitle.toString(),
                            title = child.description.title.toString(),
                            artistInfo,
                            albumId = child.description.extras?.getString(METADATA_KEY_ALBUM_ID) ?: "0",
                            numTrack = child.description.extras?.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER)?.toInt() ?: 1,
                            bitrate = null,
                            playable = true,
                            playbackRes = musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(child.mediaId!!),
                            child.description.mediaUri ?: Uri.EMPTY
                        )
                    }
                )
                itemsList.add(AlbumDetailFootItem(children.size, headerItem!!.subtitle ?: "0", headerItem!!.artist))
            }
            _albumDetailData.postValue(itemsList)
        }
    }

    /**
     * 当当前媒体项发生变化时会执行此方法
     * 进行对应处理，将列表更新，把正在播放的项状态更改
     */
    private fun handleAlbumMusicMediaDataChanged(
        mediaMetadata: MediaMetadataCompat
    ): List<BaseItemData>{
        return _albumDetailData.value?.map {
            when (it) {
                is AlbumDetailMusicItem -> {
                    val useResId = if (it.mediaId == mediaMetadata.id) PLAYING else NO_PLAYING
                    it.copy(playbackRes = useResId)
                }
                is AlbumDetailHeaderItem -> {
                    it.copy()
                }
                else -> {
                    (it as AlbumDetailFootItem).copy()
                }
            }
        } ?: emptyList()
    }


    override fun onCleared() {
        super.onCleared()
        parentId?.let {
            musicServiceConnectionFlow.unsubscribe(it,subscriptionCallback)
        }
        metadataChangJob.cancelIfActive()
//        musicServiceConnection.nowPlaying.removeObserver(metadataObserver)
    }

}